//
//  ECSLinearLayout.m
//  ECS DevelopKit
//
//  Created by LittoCats on 9/1/14.
//  Copyright (c) 2014 Littocats. All rights reserved.
//

#import "ECSLinearView.h"
#import "UIKit+ECS.h"
#import "ECSUIBuilder.h"
#import "ECSObjectAttributeWrapper.h"

@interface ECSLinearView ()<ECSAutoLayoutProtocol,ECSAutoLayout>

@property (nonatomic, strong) NSMutableArray *linearviews;

@end

@implementation ECSLinearView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.linearviews = [NSMutableArray new];
    }
    return self;
}

#pragma mark-
- (void)addSubview:(UIView *)view
{
    [super addSubview:view];
    [_linearviews addObject:view];
    [self parseContraintsForView:view];
}

- (void)willRemoveSubview:(UIView *)subview
{
    [subview willRemoveSubview:subview];
    UIView *lastLinearview = [_linearviews lastObject];
    [_linearviews removeObject:subview];
    if (subview == lastLinearview){
        if ([self.ecsAttributes[@"size"][@"width"] isEqualToString:@"wrap_content"])
            [self ecs_AutoLayoutWrapContentWidth];
        if ([self.ecsAttributes[@"size"][@"height"] isEqualToString:@"wrap_content"])
            [self ecs_AutoLayoutWrapContentHeight];
    }
    subview.translatesAutoresizingMaskIntoConstraints = YES;
}

#pragma mark- constraints parse and remove ,linearlayout 的布局实现
- (void)parseContraintsForView:(UIView *)subView
{
    subView.translatesAutoresizingMaskIntoConstraints = NO;
    
    NSLayoutConstraint *constraintHor;
    NSLayoutConstraint *constraintVer;
    NSLayoutConstraint *constraintWidth;
    NSLayoutConstraint *constraintHeight;
    
    ECS_Margin margin = ECS_MarginFromString(ECS_WrappedObjectAttribute(subView, [ECS_UIViewMarginKey UTF8String]));
    ECS_Padding padding = ECS_PaddingFromString(ECS_WrappedObjectAttribute(self, [ECS_UIViewPaddingKey UTF8String]));
    ECS_UIViewAlignMode align = ECS_UIViewAlignModeFromString(ECS_WrappedObjectAttribute(subView, [ECS_UIViewAlignKey UTF8String]));
    
    if (self.orientation == ECSLinearOrientationVertical) {
        NSLayoutAttribute attributeHor = (align & (ECS_UIViewAlignModeLeft | ECS_UIViewAlignModeRight)) == (ECS_UIViewAlignModeLeft | ECS_UIViewAlignModeRight) ? NSLayoutAttributeCenterX : align & ECS_UIViewAlignModeRight ? NSLayoutAttributeRight : NSLayoutAttributeLeft;
        CGFloat constantHor = attributeHor == NSLayoutAttributeLeft ? padding.left + margin.left : attributeHor == NSLayoutAttributeRight ? - padding.right - margin.right : 0;
        constraintHor = [NSLayoutConstraint constraintWithItem:subView
                                                     attribute:attributeHor
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:attributeHor
                                                    multiplier:1
                                                      constant:constantHor];
        
        NSLayoutAttribute attributeVer = NSLayoutAttributeTop;
        NSInteger index = [self.linearviews indexOfObject:subView];
        UIView *relativeView = index ? self.linearviews[index - 1] : self;
        NSLayoutAttribute r_attributeVer;
        CGFloat constantVer;
        if (self == relativeView){
            r_attributeVer = attributeVer;
            constantVer = attributeVer == NSLayoutAttributeTop ? padding.top + margin.top : - padding.bottom - margin.bottom;
        }else{
            r_attributeVer = attributeVer == NSLayoutAttributeTop ? NSLayoutAttributeBottom : NSLayoutAttributeTop;
            ECS_Margin r_margin = ECS_MarginFromString(ECS_WrappedObjectAttribute(relativeView, [ECS_UIViewMarginKey UTF8String]));
            constantVer = attributeVer == NSLayoutAttributeTop ? r_margin.bottom + margin.top : - r_margin.top - margin.bottom;
        }
        constraintVer = [NSLayoutConstraint constraintWithItem:subView
                                                     attribute:attributeVer
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:relativeView
                                                     attribute:r_attributeVer
                                                    multiplier:1
                                                      constant:constantVer];
        
        //解析宽高 如果宽高与 self 无关，则使用 BlankView 的计算方法
        id width = subView.ecsAttributes[@"size"][@"width"];
        width = [width isEqual:@"fill_parent"] ? @"%100" : width;
        if ([width isKindOfClass:[NSString class]] && [width hasSuffix:@"%"]) {
            CGFloat multiplier = [width integerValue]/100.0;
            constraintWidth = [NSLayoutConstraint constraintWithItem:subView
                                                           attribute:NSLayoutAttributeWidth
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self
                                                           attribute:NSLayoutAttributeWidth
                                                          multiplier:multiplier
                                                            constant:-multiplier*(padding.left+padding.right)-margin.left-margin.right];
        }else{
            if ([width isEqual:@"wrap_content"] && [subView respondsToSelector:@selector(ecs_AutoLayoutWrapContentWidth)]) {
                [(id<ECSAutoLayoutProtocol>)subView ecs_AutoLayoutWrapContentWidth];
            }else{
                CGFloat widthValue = [width floatValue];
                constraintWidth = [NSLayoutConstraint constraintWithItem:subView
                                                               attribute:NSLayoutAttributeWidth
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:self
                                                               attribute:NSLayoutAttributeWidth
                                                              multiplier:0
                                                                constant:widthValue ? widthValue : subView.frame.size.width];
            }
        }
        
        id height = subView.ecsAttributes[@"size"][@"height"];
        if ([height isEqual:@"fill_parent"]){
            constraintHeight = [NSLayoutConstraint constraintWithItem:subView
                                                            attribute:attributeVer == NSLayoutAttributeTop ? NSLayoutAttributeBottom : NSLayoutAttributeTop
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:attributeVer == NSLayoutAttributeTop ? NSLayoutAttributeBottom : NSLayoutAttributeTop
                                                           multiplier:1
                                                             constant:attributeVer == NSLayoutAttributeTop ? - padding.bottom - margin.bottom : padding.top + margin.top];
        }else if ([height isKindOfClass:[NSString class]] && [height hasSuffix:@"%"]){
            CGFloat multiplier = [height integerValue]/100.0;
            constraintHeight = [NSLayoutConstraint constraintWithItem:subView
                                                           attribute:NSLayoutAttributeHeight
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self
                                                           attribute:NSLayoutAttributeHeight
                                                          multiplier:multiplier
                                                            constant:-multiplier*(padding.top+padding.bottom)-margin.top-margin.bottom];
        }else{
            if ([height isEqual:@"wrap_content"] && [subView respondsToSelector:@selector(ecs_AutoLayoutWrapContentHeight)]) {
                [(id<ECSAutoLayoutProtocol>)subView ecs_AutoLayoutWrapContentHeight];
            }else{
                CGFloat heightValue = [height floatValue];
                constraintHeight = [NSLayoutConstraint constraintWithItem:subView
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:nil
                                                               attribute:NSLayoutAttributeNotAnAttribute
                                                              multiplier:0
                                                                constant:heightValue ? heightValue : subView.frame.size.height];
            }
        }
    }else{
        NSLayoutAttribute attributeVer = (align & (ECS_UIViewAlignModeTop | ECS_UIViewAlignModeBottom)) == (ECS_UIViewAlignModeTop | ECS_UIViewAlignModeBottom) ? NSLayoutAttributeCenterY : align & ECS_UIViewAlignModeBottom ? NSLayoutAttributeBottom : NSLayoutAttributeTop;
        CGFloat constantVer = attributeVer == NSLayoutAttributeTop ? padding.top + margin.top : attributeVer == NSLayoutAttributeBottom ? - padding.bottom - margin.bottom : 0;
        constraintVer = [NSLayoutConstraint constraintWithItem:subView
                                                     attribute:attributeVer
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:attributeVer
                                                    multiplier:1
                                                      constant:constantVer];
        
        NSLayoutAttribute attributeHor = NSLayoutAttributeLeft;
        NSInteger index = [self.linearviews indexOfObject:subView];
        UIView *relativeView = index ? self.linearviews[index - 1] : self;
        NSLayoutAttribute r_attributeHor;
        CGFloat constantHor;
        if (self == relativeView){
            r_attributeHor = attributeHor;
            constantHor = attributeHor == NSLayoutAttributeLeft ? padding.left + margin.left : - padding.right - margin.right;
        }else{
            r_attributeHor = attributeHor == NSLayoutAttributeLeft ? NSLayoutAttributeRight : NSLayoutAttributeLeft;
            ECS_Margin r_margin = ECS_MarginFromString(ECS_WrappedObjectAttribute(relativeView, [ECS_UIViewMarginKey UTF8String]));
            constantHor = attributeHor == NSLayoutAttributeLeft ? r_margin.right + margin.left : - r_margin.left - margin.right;
        }
        constraintHor = [NSLayoutConstraint constraintWithItem:subView
                                                     attribute:attributeHor
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:relativeView
                                                     attribute:r_attributeHor
                                                    multiplier:1
                                                      constant:constantHor];
        
        //解析宽高 如果宽高与 self 无关，则使用 BlankView 的计算方法
        id height = subView.ecsAttributes[@"size"][@"height"];
        height = [height isEqual:@"fill_parent"] ? @"%100" : height;
        if ([height isKindOfClass:[NSString class]] && [height hasSuffix:@"%"]) {
            CGFloat multiplier = [height integerValue]/100.0;
            constraintHeight = [NSLayoutConstraint constraintWithItem:subView
                                                           attribute:NSLayoutAttributeHeight
                                                           relatedBy:NSLayoutRelationEqual
                                                              toItem:self
                                                           attribute:NSLayoutAttributeHeight
                                                          multiplier:multiplier
                                                            constant:-multiplier*(padding.top+padding.bottom)-margin.top-margin.bottom];
        }else{
            if ([height isEqual:@"wrap_content"] && [subView respondsToSelector:@selector(ecs_AutoLayoutWrapContentHeight)]) {
                [(id<ECSAutoLayoutProtocol>)subView ecs_AutoLayoutWrapContentHeight];
            }else{
                CGFloat heightValue = [height floatValue];
                constraintHeight = [NSLayoutConstraint constraintWithItem:subView
                                                               attribute:NSLayoutAttributeHeight
                                                               relatedBy:NSLayoutRelationEqual
                                                                  toItem:self
                                                               attribute:NSLayoutAttributeHeight
                                                              multiplier:0
                                                                constant:heightValue ? heightValue : subView.frame.size.height];
            }
        }
        
        id width = subView.ecsAttributes[@"size"][@"width"];
        if ([width isEqual:@"fill_parent"]){
            constraintWidth = [NSLayoutConstraint constraintWithItem:subView
                                                            attribute:attributeHor == NSLayoutAttributeLeft ? NSLayoutAttributeRight : NSLayoutAttributeLeft
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:attributeHor == NSLayoutAttributeLeft ? NSLayoutAttributeRight : NSLayoutAttributeLeft
                                                           multiplier:1
                                                             constant:attributeHor == NSLayoutAttributeLeft ? - padding.right - margin.right : padding.left + margin.left];
        }else if ([width isKindOfClass:[NSString class]] && [width hasSuffix:@"%"]){
            CGFloat multiplier = [width integerValue]/100.0;
            constraintWidth = [NSLayoutConstraint constraintWithItem:subView
                                                            attribute:NSLayoutAttributeWidth
                                                            relatedBy:NSLayoutRelationEqual
                                                               toItem:self
                                                            attribute:NSLayoutAttributeWidth
                                                           multiplier:multiplier
                                                             constant:-multiplier*(padding.left+padding.right)-margin.left-margin.right];
        }else{
            if ([width isEqual:@"wrap_content"] && [subView respondsToSelector:@selector(ecs_AutoLayoutWrapContentWidth)]) {
                [(id<ECSAutoLayoutProtocol>)subView ecs_AutoLayoutWrapContentWidth];
            }else{
                CGFloat widthValue = [width floatValue];
                constraintWidth = [NSLayoutConstraint constraintWithItem:subView
                                                                attribute:NSLayoutAttributeWidth
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:nil
                                                                attribute:NSLayoutAttributeNotAnAttribute
                                                               multiplier:0
                                                                 constant:widthValue ? widthValue : subView.frame.size.width];
            }
        }
    }
    
    constraintWidth ? [self addConstraint:constraintWidth] : nil;
    constraintHeight ? [self addConstraint:constraintHeight] : nil;
    [self addConstraint:constraintHor];
    [self addConstraint:constraintVer];
}

#pragma mark-
- (void)ecs_AutoLayoutWrapContentWidth
{
    if (self.orientation == ECSLinearOrientationVertical)
        @throw [[NSException alloc] initWithName:@"ECSLinearView" reason:@"纵向排列子视图时，width 属性暂不能为 wrap_content ." userInfo:nil];
    NSLayoutConstraint *constraint = ECS_WrappedObjectAttribute(self, ecs_AutoLayoutWrapContentWidthKey);
    [self removeConstraint:constraint];
    
    UIView *relativeView = [self.linearviews lastObject];
    ECS_Margin margin = ECS_MarginFromString(ECS_WrappedObjectAttribute(relativeView, [ECS_UIViewMarginKey UTF8String]));
    ECS_Padding padding = ECS_PaddingFromString(ECS_WrappedObjectAttribute(self, [ECS_UIViewPaddingKey UTF8String]));
    constraint = [NSLayoutConstraint constraintWithItem:self
                                              attribute:relativeView ? NSLayoutAttributeRight : NSLayoutAttributeWidth
                                              relatedBy:NSLayoutRelationEqual
                                                 toItem:relativeView
                                              attribute:relativeView ? NSLayoutAttributeRight : NSLayoutAttributeNotAnAttribute
                                             multiplier:1
                                               constant:margin.right+padding.right+ (relativeView ? 0 : padding.left)];
    if (!self.translatesAutoresizingMaskIntoConstraints)
        [self.superview addConstraint:constraint];
}
- (void)ecs_AutoLayoutWrapContentHeight
{
    if (self.orientation == ECSLinearOrientationHorizontal)
        @throw [[NSException alloc] initWithName:@"ECSLinearView" reason:@"横向排列子视图时，height 属性暂不能为 wrap_content ." userInfo:nil];
    NSLayoutConstraint *constraint = ECS_WrappedObjectAttribute(self, ecs_AutoLayoutWrapContentHeightKey);
    [self removeConstraint:constraint];
    
    UIView *relativeView = [self.linearviews lastObject];
    ECS_Margin margin = ECS_MarginFromString(ECS_WrappedObjectAttribute(relativeView, [ECS_UIViewMarginKey UTF8String]));
    ECS_Padding padding = ECS_PaddingFromString(ECS_WrappedObjectAttribute(self, [ECS_UIViewPaddingKey UTF8String]));
    constraint = [NSLayoutConstraint constraintWithItem:self
                                              attribute:relativeView ? NSLayoutAttributeBottom : NSLayoutAttributeHeight
                                              relatedBy:NSLayoutRelationEqual
                                                 toItem:relativeView
                                              attribute:relativeView ? NSLayoutAttributeBottom : NSLayoutAttributeNotAnAttribute
                                             multiplier:1
                                               constant:margin.bottom+padding.bottom + (relativeView ? 0 : padding.top)];
    if (!self.translatesAutoresizingMaskIntoConstraints)
        [self.superview addConstraint:constraint];
}



#pragma mark- @autoLayoutAttributes
+ (NSDictionary *)autoLayoutAttributes
{
//    @"contentAlign":@[@"left|top",[[self superclass] autoLayoutAttributes][@"align"][2]],
    return @{@"orientation":@[@"ver", ^NSNumber *(NSString *orientation){return @([[orientation lowercaseString] UTF8String][0]);}]};
}
@end

@interface ECSUIAttributesParser (ECSLinearView)

@end

@implementation ECSUIAttributesParser (ECSLinearView)

@end